﻿using System.Collections.Generic;
using QFramework;
using TodoPro.System.Command;
using TodoPro.System.Event;
using TodoPro.System.Query;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

namespace TodoPro.Runtime
{
	public class TodoProRuntime : MonoBehaviour
	{
		private Transform mTodoGameObjRoot;
		private Transform mTodoItemPrefab;
		
		private List<Todo> mTodos = null;

		private TodoEventSystemNode mEventSystemNode;

		private void Awake()
		{
			mEventSystemNode = TodoEventSystemNode.Allocate();
			
			mEventSystemNode.Register<OnTodoRemoveEvent>(@event =>
			{
				mTodos = new GetTodosByFilterQuery()
					.Do();
					
				RefreshView();
			});
			
			mEventSystemNode.Register<OnTodoAddEvent>(@event =>
			{
				mTodos = new GetTodosByFilterQuery()
					.Do();
					
				RefreshView();
			});
			
			mEventSystemNode.Register<OnFilterChangedEvent>(@event =>
			{
				mTodos = new GetTodosByFilterQuery()
					.Do();
					
				RefreshView();
			});

			var contentInput = transform.Find("ContentInput").GetComponent<InputField>();
			var btnAdd = transform.Find("BtnAdd").GetComponent<Button>();
			
			btnAdd.onClick.AddListener(() =>
			{
				TodoProConfig.SendCommand(new AddTodoCommand(contentInput.text));
				contentInput.text = string.Empty;
			});

			mTodoGameObjRoot = transform.Find("Todos");
			mTodoItemPrefab = transform.Find("TodoItemPrefab");


			var group = transform.Find("ToggleGroup");


			var allToggle = group.Find("All").GetComponent<Toggle>();
			var activeToggle = group.Find("Active").GetComponent<Toggle>();
			var completedToggle = group.Find("Completed").GetComponent<Toggle>();
			
			allToggle.onValueChanged.AddListener(isOn =>
			{
				if (isOn)
				{
					//
					TodoProConfig.SendCommand(new ChangeFilterCommand(TodoFilter.All));
				}
			});
			
			activeToggle.onValueChanged.AddListener(isOn =>
			{
				if (isOn)
				{
					//
					TodoProConfig.SendCommand(new ChangeFilterCommand(TodoFilter.Active));
				}
			});
			
			completedToggle.onValueChanged.AddListener(isOn =>
			{
				if (isOn)
				{
					//
					TodoProConfig.SendCommand(new ChangeFilterCommand(TodoFilter.Completed));
				}
			});


			TodoProConfig.GetModel<ITodoModel>().Load();

			mTodos = new GetTodosByFilterQuery()
				.Do();
			
			RefreshView();
		}

		void RefreshView()
		{
			foreach (Transform childTransform in mTodoGameObjRoot)
			{
				Destroy(childTransform.gameObject);
			}
			
			mTodos.ForEach(todoData =>
			{
				var todoItem = Instantiate(mTodoItemPrefab,mTodoGameObjRoot);
				var text = todoItem.transform.Find("Content").GetComponent<Text>();
				text.text = todoData.Content;

				var toggle = todoItem.transform.Find("Toggle").GetComponent<Toggle>();

				todoData.FinishedProperty.Bind(value =>
				{
					mTodos = new GetTodosByFilterQuery()
						.Do();
					
					RefreshView();
					
				}).AddTo(toggle);
				
				toggle.isOn = todoData.Finished;

				// 完成
				toggle.onValueChanged.AddListener((isOn) =>
				{
					if (isOn)
					{
						// 发送 FinishTodoCommand
						TodoProConfig.SendCommand(new FinishTodoCommand(todoData.Id));
					}
					else
					{
						TodoProConfig.SendCommand(new ResetTodoCommand(todoData.Id));
					}
				});
				
				
				var btnDelete = todoItem.transform.Find("BtnDelete").GetComponent<Button>();
				
				btnDelete.onClick.AddListener(() =>
				{
					TodoProConfig.SendCommand(new RemoveTodoCommand(todoData.Id));
				});
				
				todoItem.gameObject.SetActive(true);
			});
		}

		private void OnDestroy()
		{
			mEventSystemNode.Recycle2Cache();
			mEventSystemNode = null;
			
			TodoProConfig.GetModel<ITodoModel>().Save();
			
			TodoProConfig.DisposeConfig();
		}
	}
}